<?php
/**
 * 
 * @author Alan Moreau - moreau.alan@gmail.com
 */
class Mac_Application
{
    /**
     * Defines available running environment  
     * 
     * @var array<String>
     */
    private static $RUNNING_ENV = array('dev' => 'developpement', 
                                        'prod' => 'production');
    
    /**
     * 
     * 
     * @var 
     */
    private static $APPLICATION_INCLUDE_PATHS = array('application', 
                                                      'library',
                                                      'config');
    
    /**
     * Defines current running environment
     * @see Application::$MAC_RUNNING_ENV
     * @var string
     */
    private $env = null;
    
    /**
     * Defines debug mode
     * 
     * @var boolean
     */
    private $debug = false;
    
    /**
     * Defines project base path
     * 
     * @var string
     */
    private $basePath = "";
    
    /**
     * Application configuration parameters
     * 
     * @var array string
     */
    private $config = null;
    
    /**
     * Loads application configuration
     * array('base_path' => '%basePath%',
     *       'debug_mode' => '0|1')
     * 
     * @param array $config
     */
    public function __construct ()
    {
        mb_internal_encoding('utf8');
        
        array_walk(self::$APPLICATION_INCLUDE_PATHS, function(&$path){
            $path = realpath(ROOT_PATH . '/' . $path);
        });
        $paths = implode(PATH_SEPARATOR, self::$APPLICATION_INCLUDE_PATHS);
        set_include_path($paths . PATH_SEPARATOR . get_include_path());
        
        require_once('library/Mac/Autoloader.php');
        spl_autoload_register(array('Mac_Autoloader','autoload'));
        
        define('APPLICATION_PATH', ROOT_PATH . '/application');
        define('DOCROOT_PATH', ROOT_PATH . '/docroot');
        define('LAYOUT_PATH', APPLICATION_PATH . '/layout');
        define('MODULES_PATH', APPLICATION_PATH . '/module');
        
        define('FRONT_JAVASCRIPT_PATH', '/js');
        define('FRONT_CSS_PATH', '/css');
        define('FRONT_IMAGE_PATH', '/image');

        //bootstrap logger
        if(Mac_Configuration::exists('system', 'log_path')){
            define('LOG_PATH', Mac_Configuration::get('system', 'log_path'));
        } else {
            die("Cannot bootstrap logger : 'log_path' configuration parameter is missing in 'config/system.php'");
        }
        
        set_error_handler(array('Mac_ErrorHandler', 'handleError'));
        set_exception_handler(array('Mac_ErrorHandler', 'handleException'));
                
        //check environnement configuration
        $this->env = getenv('RUNNING_ENV');
        if($this->env === false){
            die('Environment variable RUNNING_ENV is not defined');
        }
        if(!in_array($this->env, self::$RUNNING_ENV)){
            die('Value of RUNNING_ENV is not valid : '.$this->env);
        }
        
        //runtime configuration depends on running env
        if($this->env === self::$RUNNING_ENV['dev']){
            error_reporting(E_ALL);
            ini_set('display_errors', 1);
            ini_set('display_startup_errors', 1);
        } else if($this->env === self::$RUNNING_ENV['prod']){
            error_reporting(E_ALL ^ E_NOTICE);
            ini_set('display_errors', 0);
            ini_set('display_startup_errors', 0);
        }
        
        Mac_Db_Connection::configure(
            Mac_Configuration::get('database', 'host'),
            Mac_Configuration::get('database', 'user'),
            Mac_Configuration::get('database', 'pass'),
            Mac_Configuration::get('database', 'name')
        );
        Mac_Db_Connection::connect();
        
        date_default_timezone_set("Europe/Paris");
        
        $this->debug = (Mac_Configuration::exists('debug', 'enabled') && Mac_Configuration::get('debug', 'enabled') == true);
        $this->bootstrap();
    }
    
    public function start ()
    {
        $request = new Mac_Controller_HTTPRequest();
        $frontController = Mac_Controller_Front::getInstance();
        $frontController->dispatch($request);
    }
    
    /**
     * Configure all components :
     * - Front controller
     */
    private function bootstrap ()
    {
        //bootstrap front controller
        $frontController = Mac_Controller_Front::getInstance();
        if(Mac_Configuration::exists('system', 'error_controller', 'module')
            && Mac_Configuration::exists('system', 'error_controller', 'controller')){
            if(Mac_Configuration::get('system', 'error_controller', 'action')){
                $frontController->setErrorControllerMCA(Mac_Configuration::get('system', 'error_controller', 'module'),
                                                        Mac_Configuration::get('system', 'error_controller', 'controller'),
                                                        Mac_Configuration::get('system', 'error_controller', 'action'));
                    
            } else {
                $frontController->setErrorControllerMCA(Mac_Configuration::get('system', 'error_controller', 'module'),
                                                        Mac_Configuration::get('system', 'error_controller', 'controller'));
            }
        } else {
            die("Cannot bootstrap front controller : 'error_controller' configuration parameters is invalid");
        }
        
        if(Mac_Configuration::exists('system', 'default_controller', 'module')
            && Mac_Configuration::exists('system', 'default_controller', 'controller')){
            if(Mac_Configuration::get('system', 'default_controller', 'action')){
                $frontController->setDefaultControllerMCA(Mac_Configuration::get('system', 'default_controller', 'module'),
                                                          Mac_Configuration::get('system', 'default_controller', 'controller'),
                                                          Mac_Configuration::get('system', 'default_controller', 'action'));
                    
            } else {
                $frontController->setDefaultControllerMCA(Mac_Configuration::get('system', 'default_controller', 'module'),
                                                          Mac_Configuration::get('system', 'default_controller', 'controller'));
            }
        } else {
            die("Cannot bootstrap front controller : 'default_controller' configuration parameters is invalid");
        }
    }
}
